package com.geek.novel.services.impl

import com.geek.novel.bo.AppContext
import com.geek.novel.entity.BookIndex
import com.geek.novel.entity.BookRead
import com.geek.novel.entity.BookSection
import com.geek.novel.services.BookRepository
import com.geek.novel.services.ImportBookService
import com.geek.novel.utils.LogCatUtil
import com.geek.novel.utils.ToastUtils
import com.vicpin.krealmextensions.save
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import org.mozilla.universalchardet.UniversalDetector
import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
import java.io.InputStreamReader
import java.util.regex.Pattern

class ImportBookServiceImpl : ImportBookService {

    private val bookRepository = BookRepository.getInstance()

    override fun importBook(file: File): Observable<Any?> {
        return Observable.create { emitter: ObservableEmitter<Any?>? ->
            run {
                try {
                    val book = saveBook(file)
                    emitter?.onNext(book)
                    saveChapter(file, book)
                    emitter?.onComplete()
                } catch (e: Exception) {
                    LogCatUtil.e("???", e.message, e)
                    emitter?.onError(e)
                }
            }
        }
    }

    /**
     * 保存书籍
     */
    private fun saveBook(file: File): BookRead{
        var name = file.name
        val indexOf: Int = name.indexOf(".")
        if(indexOf > -1){
            name = name.substring(0, indexOf)
        }
        val book = BookRead(name)
        book.initEntity()
        //id加个-号，防止出现重复
        book.bookId = "-"+book.id
        book.local = true
        book.collect = true
        bookRepository.saveBookToTop(book)
        book.save()
        AppContext.getContext().doOnMainThread{
            ToastUtils.toast("已获取书籍：《${name}》，正在导入章节信息")
        }
        return book
    }

    private fun saveChapter(file: File, book: BookRead) {
        val regex = "第.{1,7}章.*"
        var encoding: String
        var fis: FileInputStream? = FileInputStream(file)
        val buf = ByteArray(4096)
        val detector = UniversalDetector(null)
        var nread: Int
        while (fis!!.read(buf).also { nread = it } > 0 && !detector.isDone) {
            detector.handleData(buf, 0, nread)
        }
        detector.dataEnd()
        encoding = detector.detectedCharset
        if (encoding == null || encoding.isEmpty()) encoding = "utf-8"
        fis.close()
        var chapterPageIndex = 0
        var title: String? = null
        val contentBuilder = StringBuilder()
        fis = FileInputStream(file)
        val inputReader = InputStreamReader(fis, encoding)
        val buffReader = BufferedReader(inputReader)
        var line: String?
        while (buffReader.readLine().also { line = it } != null) {
            val curLine = line!!
            val p = Pattern.compile(regex)
            val m = p.matcher(curLine)
            if (m.find()) {
                val temp = curLine.trim { it <= ' ' }.substring(0, curLine.trim { it <= ' ' }.indexOf("第"))
                if (temp.trim { it <= ' ' }.isNotEmpty()) {
                    contentBuilder.append(temp)
                }
                if (contentBuilder.toString().isNotEmpty()) {
                    if (contentBuilder.toString().replace("　".toRegex(), "").trim { it <= ' ' }.isNotEmpty()) {
                        saveDurChapterContent(chapterPageIndex, title, contentBuilder.toString(), book)
                        chapterPageIndex++
                    }
                    contentBuilder.delete(0, contentBuilder.length)
                }
                title = curLine.trim { it <= ' ' }.substring(curLine.trim { it <= ' ' }.indexOf("第"))
            } else {
                if (curLine.trim { it <= ' ' }.isEmpty()) {
                    if (contentBuilder.isNotEmpty()) {
                        contentBuilder.append("\r\n")
                    } else {
                        contentBuilder.append("\r")
                    }
                } else {
                    contentBuilder.append(curLine)
                    if (title == null) {
                        title = curLine.trim { it <= ' ' }
                    }
                }
            }
        }
        if (contentBuilder.isNotEmpty()) {
            saveDurChapterContent(chapterPageIndex, title, contentBuilder.toString(), book)
            contentBuilder.delete(0, contentBuilder.length)
        }
        buffReader.close()
        inputReader.close()
        fis.close()

        LogCatUtil.i(this.javaClass.simpleName, "导入书籍(${book.bookName})完成")
        AppContext.getContext().doOnMainThread{
            ToastUtils.toast("《${book.bookName}》已导入完成")
        }
    }

    /**
     * 保存章节内容
     * @param chapterPageIndex  章节下标
     * @param title              标题名称
     * @param content           章节内容
     */
    private fun saveDurChapterContent(chapterPageIndex: Int, title: String?, content: String, book: BookRead) {
        LogCatUtil.i(this.javaClass.simpleName, "导入书籍(${book.bookName})章节(${chapterPageIndex})：${title}")
        val section = BookSection()
        section.initEntity()
        section.bookId = book.bookId
        section.title = title
        section.content = content

        val index = BookIndex()
        index.initEntity()
        index.bookId = book.bookId
        index.sectionId = section.id
        index.indexName = title
        index.crawler = true

        section.indexId = index.id

        section.save()
        index.save()

    }
}